home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
FROMUTS
/
UNIXLIB37B
/
src
/
c
/
mktime
< prev
next >
Wrap
Text File
|
1991-10-08
|
3KB
|
155 lines
static char sccs_id[] = "@(#) mktime.c 3.0 "__DATE__" HJR";
/* mktime.c (c) Copyright 1990 H.Rogers */
#include <time.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
static unsigned int __tmonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
static struct tm __tz[1] = /* time struct */
{
{ 0,0,0,0,0,0,0,0,-1,0,"" }
};
/* Time zones are "[TZNAME][H][:M][DSTNAME]" where H:M gives the time *west*
* of GMT for the timezone. If DSTNAME appears then the time zone follows
* DST rules according to DSTNAME. Examples:
*
* "EST5EDT" USA Eastern time zone
* "CST6CDT" USA Central time zone
* "NFLDT3:30NFLD" Newfoundland time (1:30 ahead of Eastern)
* "OZCST-9:30" Australian Central time zone (no DST)
*
* DST is currently unimplemented: Other implementations involve very nasty
* code in order to cater for exception years (e.g. USA 1972). Also most
* assume USA rules for DST (which have changed 3 times since 1970), not UK
* rules (which have changed more often and are more complex :-( ). It's
* simpler to rely on the SysAdmin changing the system clock twice a year
* according to local custom. Leap seconds and the century offset are ignored,
* but the routines are correct to within a second till at least 2038... */
int timezone = 0;
void tzset(void)
{
char *z;
register int i;
if (!(z = getenv("TZ")))
z = "GMT0UK"; /* default to GMT/UKDST */
i = 0; while (isalpha(*z))
{
if (i < 3)
{ __tz->tm_zone[i] = *z; i++; }
z++;
}
__tz->tm_zone[i] = 0;
i = (int)strtol(z,&z,10) * 3600;
if (*z == ':')
{ z++; i += (int)strtol(z,&z,10) * 60; }
__tz->tm_gmtoff = timezone = i;
}
static struct tm *__mktm(register time_t);
struct tm *gmtime(register const time_t *tp)
{
if (!(__tz->tm_zone[0])) tzset();
return(__mktm(*tp));
}
struct tm *localtime(register const time_t *tp)
{
if (!(__tz->tm_zone[0])) tzset();
return(__mktm((*tp) - __tz->tm_gmtoff));
}
static struct tm *__mktm(register time_t tm)
{
register struct tm *t = __tz;
register time_t i,j,k;
t->tm_isdst = -1;
t->tm_wday = (tm / 86400 + 4) % 7; /* 1st Jan 1970 = Thursday */
t->tm_sec = tm % 60; tm /= 60;
t->tm_min = tm % 60; tm /= 60;
t->tm_hour = tm % 24; tm /= 24;
i = (365<<1); /* two years */
if (tm >= i) /* >= 1972 */
{
j = (tm - i) / 1461;
tm -= i + j * 1461;
k = tm ? ((tm - 1) / 365) : 0;
if (k)
{
tm -= 1 + k * 365;
__tmonth[1] = 28;
}
else
__tmonth[1] = 29; /* Feb. hath 29 days in a leap year */
k += 2 + (j<<2);
}
else /* < 1972 */
{
k = tm / 365;
tm -= k * 365;
__tmonth[1] = 28;
}
t->tm_year = k + 70;
t->tm_yday = tm;
k = tm; j = 0; while(k >= (i = __tmonth[j])) k -= i,j++;
t->tm_mon = j;
t->tm_mday = k + 1;
return(t);
}
time_t mktime(register struct tm *t)
{
register time_t r;
if ((t->tm_year - 70) < 0) return((time_t)-1);
r = t->tm_year - 70;
if (r < 2)
r = r * 365;
else
{
register int i,j;
i = (r - 2) & 3;
j = ((r - 2)>>2) * 1461;
if (i)
{
r = (365<<1) + j + 1 + i * 365;
}
else
r = (365<<1) + j;
}
r += t->tm_yday;
r = r * 24 + t->tm_hour;
r = r * 60 + t->tm_min;
r = r * 60 + t->tm_sec;
r += t->tm_gmtoff; /* mktime() is passed a localtime() struct */
return(r);
}